import 'package:flutter/cupertino.dart';
import 'package:flutter_deer/util/other_utils.dart';
import 'package:flutter_deer/util/print/print_base_engine.dart';
import 'package:flutter_deer/util/print/data/print_format_des.dart';
import 'package:flutter_deer/util/toast_utils.dart';

import '../../net/conmmon_net_util.dart';
import '../../net/dio_utils.dart';
import '../../net/http_api.dart';

///https://www.poscom.cn/index.php?id=152
class PrintEngineGb extends IPrintBaseEngine {
  final reqTime = DateTime.now().millisecondsSinceEpoch;
  final memberCode = '1FF5CF34A541A4259E82E04A5988033A';
  final apiKey = '7C3581H4VD2C2BCTFGJKFV77V6SAC0NH';
  final deviceID = '00164263667139276';

  // 单例
  static final PrintEngineGb _instance = PrintEngineGb._internal();

  factory PrintEngineGb() => _instance;

  PrintEngineGb._internal();

  @override
  Future<void> init({
    required Map<String, dynamic> config,
    required Function(dynamic) onError,
    required Function() onComplete,
  }) async {}

  @override
  Future<void> executePrint(List<BasePrintBean> printBeans) async {
    for (var value in printBeans) {
      print(value.toString());
    }
    final printStr = StringBuffer();
    for (final printBean in printBeans) {
      //<gpWord Align=a Bold=x Wsize=y Hsize=z Reverse=k Underline=j>文本内容</gpWord>
      // Align（对齐）: 0: 左对齐, 1: 居中, 2: 右对齐
      // Bold（加粗）: 0: 不加粗, 1: 加粗
      // Wsize（字体宽度）: 倍数计算,范围[0, 8]
      // Hsize（字体高度）: 倍数计算,范围[0, 8]
      // Reverse（反显）: 0: 不反显（黑字白底）, 1: 反显（黑底白字）
      // Underline（下划线）: 0: 没下划线, 1: 有下划线
      if (printBean is TextPrintBean) {
        final align = printBean.alignment;
        final bold = printBean.isBold ? 1 : 0;
        final wsize = printBean.textSize == BasePrintBean.TEXT_SIZE_BIG ? 1 : 0;
        final hsize = printBean.textSize == BasePrintBean.TEXT_SIZE_BIG ? 1 : 0;
        final reverse = '0';
        final underline = printBean.isUnderLine ? '1' : '0';
        final text = printBean.text;
        final gpWord = '<gpWord Align=$align Bold=$bold Wsize=$wsize Hsize=$hsize Reverse=$reverse Underline=$underline>$text</gpWord>';
        printStr.write(gpWord);
      }
      if (printBean is ColumnsTextPrintBean) {
        final colsTextArr = printBean.colsTextArr;
        final gpTable = generateGpTable(colsTextArr: colsTextArr, colsWidthWeightArr: printBean.getColsWidthWeightArr(), type: 0);
        printStr.write(gpTable);
      }
      if (printBean is CodePrintBean) {
        final gpCode = '<gpQRCode Align=${printBean.alignment}>${printBean.codeData}</gpQRCode>';
        printStr.write(gpCode);
      }
      if (printBean is BlankLinePrintBean) {
        final blankLineCount = printBean.blankLineCount;
        for (var i = 0; i < blankLineCount; i++) {
          const gpBlankLine = '<gpWord> </gpWord>';
          printStr.write(gpBlankLine);
        }
      }

      const gpDashLine = '<gpWord>--------------------------------</gpWord>';
      if (printBean is DashLinePrintBean) {
        printStr.write(gpDashLine);
        // print(gpDashLine);
      }

      // printStr.write(BlankLinePrintBean(alignment: 1, blankLineCount: 2));
    }
    printStr.write('<gpCut/>');

    print('----->:${printStr}');

    CommonNetUtil.requestNetworkGbPrinter<String>(Method.post, url: HttpApi.gbPrinter_sendMsg, params: {
      'reqTime': reqTime,
      'securityCode': '$memberCode${deviceID}${reqTime}${apiKey}'.toMd5,
      'memberCode': memberCode,
      'deviceID': deviceID,
      'mode': 2,
      'msgDetail': printStr.toString(),
      // 'voice': '2028',
    }, onSuccess: (data) {
      print(' 发送打印 $data');
    }, onError: (e, error) {
      Toast.show('发送失败 $error');
      print(' 发送打印失败 $error');
    });
  }

  @override
  Future<String> getStatus() async {
    return 'gb';
  }

  String generateGpTable({
    required List<String> colsTextArr,
    required List<int> colsWidthWeightArr,
    int type = 0, // 0: 58mm, 1: 80mm
  }) {
    assert(colsTextArr.length == colsWidthWeightArr.length, '列文本和列宽度权重数量必须一致');
    assert(colsTextArr.length >= 2 && colsTextArr.length <= 6, '列数必须在2到6之间');

    // final int totalWidth = type == 0 ? 32 : 48;
    // final int sumWeight = colsWidthWeightArr.reduce((a, b) => a + b);
    // assert(sumWeight == totalWidth, '列宽度权重之和必须等于$totalWidth（Type=$type）');

    final StringBuffer sb = StringBuffer();
    sb.write('<gpTable Type=${type == 0 ? 'a' : 'b'}>');

    // 构建 <tr><td>...</td></tr>
    sb.write('<tr>');
    for (int i = 0; i < colsTextArr.length; i++) {
      String text = colsTextArr[i];
      int width = colsWidthWeightArr[i];

      // 计算字符宽度（中文算2）
      int textWidth = text.characters.map((ch) => RegExp(r'[\u4e00-\u9fa5]').hasMatch(ch) ? 2 : 1).reduce((a, b) => a + b);

      // 截断或补空格
      String formattedText = _fitText(text, width, i == colsTextArr.length - 1);
      sb.write('<td>$formattedText</td>');
    }
    sb.write('</tr>');

    sb.write('</gpTable>');
    return sb.toString();
  }

  String _fitText(String text, int maxWidth, bool isLastColumn) {
    int currentWidth = text.characters.map((ch) => RegExp(r'[\u4e00-\u9fa5]').hasMatch(ch) ? 2 : 1).reduce((a, b) => a + b);

    if (currentWidth > maxWidth) {
      // 截断
      StringBuffer sb = StringBuffer();
      int count = 0;
      for (var ch in text.characters) {
        int chWidth = RegExp(r'[\u4e00-\u9fa5]').hasMatch(ch) ? 2 : 1;
        if (count + chWidth > maxWidth) break;
        sb.write(ch);
        count += chWidth;
      }
      return sb.toString();
    } else {
      // 补空格
      int pad = maxWidth - currentWidth;
      return isLastColumn ? text.padLeft(text.length + pad) : text.padRight(text.length + pad);
    }
  }
}
